﻿#include <QLabel>
#include <QDebug>
#include <QPushButton>
#include <QSpinBox>
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QSettings>
#include <QCheckBox>
#include <QStandardPaths>
#include <QMessageBox>
#include <QDateTime>
#include <QDir>
#include <QInputDialog>
#include <QCryptographicHash>

#include "calibDialog.h"
#include "mainwindow.h"
#include "./ImageProcessing/imageProcessing.h"
#include "Camera/CameraCommon/CameraImage_RGB32.h"
#include "Camera/CameraCommon/DialogCameraSelect.h"
#include "./ui_mainwindow.h"
#include "qtOpenCV/convert.h"
#define SETTINGS_FILE "/settings.ini"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    setAttribute(Qt::WA_QuitOnClose);
    ui->setupUi(this);
    connect(ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt);
    setDefaultAppInfo();

    connect(&m_focusMeasure, &Qly::FocusMeasureObject::focusMeasure, this, &MainWindow::updateFocusMeasure);
    m_focusMeasure.start(50);

    m_settingsFilePath = configFilePath() + SETTINGS_FILE;
    QDir dir(m_settingsFilePath);
    if( !dir.exists(m_settingsFilePath) ) // 如果没有ini 文件，则从程序安装路径中拷贝一份模板
    {
        QString path = qApp->applicationDirPath();
        QFile::copy(path + SETTINGS_FILE, m_settingsFilePath);
    }
    QSettings settings("JingHai Technology", "JHPhotoV2", this );
    setupMeasureView(settings);
    m_cameraImage = new Qly::CameraImage_RGB32(this);
    //m_cameraImage->setBayerPattern(AV_PIX_FMT_BAYER_BGGR8);
    connect(m_cameraImage, &Qly::CameraImage::imageChanged, m_pMeasureView, &Qly::ImageView::setImage);
    connect(m_cameraImage, &Qly::CameraImage::imageChanged, &m_focusMeasure, &Qly::FocusMeasureObject::setImage);
    setupStatusBar();
    setupLensManager(settings);

    m_password = settings.value("Global/Password", "e10adc3949ba59abbe56e057f20f883e").toString();
    connect(ui->actionPassword, SIGNAL(triggered()), this, SLOT(changePassword()));

    m_saveImagePath = settings.value("Global/SaveImagePath", QStandardPaths::PicturesLocation).toString();
    m_loadImagePath = settings.value("Global/LoadImagePath", QStandardPaths::PicturesLocation).toString();

    //lock(settings);
    connect(ui->actionOpen, &QAction::triggered, this, qOverload<>(&MainWindow::loadImage));
    //connect(ui->actionOpen, SIGNAL(triggered(bool)), this, SLOT(loadImage()));
    connect(ui->actionSaveWithMark, &QAction::triggered, this, &MainWindow::saveImageWithMark);
    connect(ui->actionSaveWithoutMark, &QAction::triggered, this, &MainWindow::saveImageWithoutMark);
    setupCamera(settings);

    setupNosepiece(settings);

    restoreGeometry(settings.value("Geometry/MainWindow").toByteArray());
    restoreState(settings.value("Geometry/windowState").toByteArray());

    setupImageProcessing();
}

MainWindow::~MainWindow()
{
    delete m_cameraFind;
    delete ui;
}

QString MainWindow::configFilePath()
{
    //    QString path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
    //    QDir dir;
    //    dir.mkpath(path);
    return qApp->applicationDirPath();
}

bool MainWindow::loadImageFromFile(QString fileName)
{
    m_cameraImage->loadImage(fileName);
    return true;
}

bool MainWindow::loadImage(QImage &image)
{
    if(image.isNull()) return false;
    m_cameraImage->setImage(image);
    return true;
}

void MainWindow::loadImage()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    QStringLiteral("Open Image"),
                                                    m_loadImagePath,
                                                    QStringLiteral("Image Files (*.png *.jpg *.bmp *.tiff)"));
    if(fileName.isEmpty())
    {
        return;
    }
    loadImageFromFile(fileName);

    m_loadImagePath = QFileInfo(fileName).path();
    //    if( !m_cameraImage->isModified() )
    //    {
    //        m_cameraImage->loadImage(fileName);
    //    }
    //    else
    //    {
    //        MainWindow * m = new MainWindow(true);
    //        m->loadImageFromFile(fileName);
    //        m->show();
    //    }
}

void MainWindow::saveImageWithMark()
{
    //QImage image = m_centerWidget->getImage(true);
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                                                    m_saveImagePath,
                                                    QStringLiteral("Images (*.jpg *.png *.bmp)"));
    if( !fileName.isEmpty () )
    {
        m_pMeasureView->saveImage(fileName, true);
    }
    m_saveImagePath = QFileInfo(fileName).path();
}

void MainWindow::saveImageWithoutMark()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                                                    m_saveImagePath,
                                                    QStringLiteral("Images (*.jpg *.png *.bmp)"));
    if( !fileName.isEmpty () )
    {
        m_pMeasureView->saveImage(fileName, false);
    }
    m_saveImagePath = QFileInfo(fileName).path();
}

void MainWindow::openDefaultCamera()
{
    qDebug() << "MainWindow::openDefaultCamera()";
    if(m_pCamera)
    {
        m_pCamera->close();
        m_pCamera->disconnect();
        delete m_pCamera;
        m_pCamera = nullptr;
    }

    QSet<Qly::CameraType> types;
    types <<  /*Qly::SYS_CAM <<*/ Qly::TOUP_USB << Qly::HIK_GIGE << Qly::HIK_USB << Qly::SYS_CAM;// << Qly::TIS_GIGE << Qly::HIK_GIGE << Qly::TOUP_USB << Qly::HIK_USB <<  Qly::SYS_CAM;

    qDebug() << "here";
    QStringList list = m_cameraFind->allCameraName(types);
    qDebug() << "openDefaultCamera Camera list = " << list;
    if(list.size() > 1)
    {
        DialogCameraSelect dia(this);
        dia.setCameraList(list);
        int ret = dia.exec();
        if(ret == QDialog::Accepted)
        {
            QString name = dia.cameraName();
            if(!name.isEmpty() )
            {
                QStringList lst = name.split(":");
                QString rawName = lst.last();
                rawName = rawName.trimmed();

                m_pCamera = m_cameraFind->findCameraByName(rawName, this);
            }
        }
    }
    else if (list.size() == 1)
    {
        m_pCamera = m_cameraFind->defaultCamera(types);
        //m_camera = m_cameraFind->findCameraByName("E3ISPM12000KPA", this);
    }
    if(m_pCamera)
    {
        m_labelCameraName->setText(tr("Camera: %1").arg(m_pCamera->deviceName()));
        connect(m_toolbarCamera, &Qly::ToolBarCamera::startCamera, m_pCamera, &Qly::IndustryCamera::startGrabbing);
        connect(m_toolbarCamera, SIGNAL(suspendCamera()), m_pCamera, SLOT(stopGrabbing()));
        connect(m_toolbarCamera, SIGNAL(setupCamera()), m_pCamera, SLOT(showVCDPropertyPage()));
        //connect(m_camera, &Qly::IndustryCamera::ImageDataChanged, this, &MainWindow::updateCameraImage);
        connect(m_pCamera, &Qly::IndustryCamera::videoFrameReady, this, &MainWindow::updateCameraFrame);
        connect(m_pCamera, SIGNAL(deviceLost()), m_toolbarCamera, SLOT(cameraLost()));

        m_toolbarCamera->defaultCameraOpened();
        QString path = configFilePath();
        m_pCamera->loadSettingsFromFile(path + "/Camera.ini");
        qInfo() << "defaultCameraOpened()";
    }
    else
    {
        m_toolbarCamera->defaultCameraFailed();
        qDebug() << "defaultCameraFailed()";
    }
}

void MainWindow::closeCamera()
{
    if(m_pCamera)
    {
        m_pCamera->close();
        m_pCamera->disconnect();
        m_cameraFind->release(m_pCamera);
        //delete m_pCamera;
        m_pCamera = nullptr;
        return;
    }
}

void MainWindow::setupMeasureView(QSettings &settings)
{
    m_pMeasureView = new Qly::MeasureView(this);
    m_pMeasureView->dataSet().setElementType(Qly::MeasureElement::None);

    //    m_centerWidget->setMousePositionPickMode(true);
    //    connect(m_centerWidget, SIGNAL(mousePosition(QPointF&)), this, SLOT(xyRelativeMove(QPointF&)));

    m_pScrollArea = new QScrollArea(this);
    //    m_scrollArea->setBackgroundRole(QPalette::Dark);
    setCentralWidget(m_pScrollArea);
    m_pScrollArea->setWidget(m_pMeasureView);
    m_pScrollArea->setAlignment(Qt::AlignCenter);

    m_pMeasureView->dataSet().loadSettings(settings);

    //    Qly::Ruler & ruler = m_pMeasureView->ruler();
    //    ruler.setEnable(true);
    //    ruler.setPosition(QPoint(200, 200));

    m_pToolbarMeasure = new Qly::ToolBarMeasure("ToolBarMeasure", this);
    m_pToolbarMeasure->attach(m_pMeasureView);
    m_pToolbarMeasure->attach(ui->menuMeasure);
    addToolBar(Qt::TopToolBarArea, m_pToolbarMeasure);


    m_pToolbarZoom = new Qly::ToolBarZoom("ToolBarZoom", this);
    m_pToolbarZoom->attach(m_pMeasureView);
    addToolBar(Qt::TopToolBarArea, m_pToolbarZoom);
    m_pToolbarZoom->loadSettings(settings);

    m_pToolbarProperty = new Qly::ToolBarProperty("ToolbarProperty", this);
    m_pToolbarProperty->attach(m_pMeasureView);
    addToolBar(Qt::TopToolBarArea, m_pToolbarProperty);
    m_pToolbarProperty->loadSettings(settings);
    addToolBarBreak();

    m_pToolbarSemiMeasure = new Qly::ToolBarSemiAutoMeasure(this);
    m_pToolbarSemiMeasure->attach(m_pMeasureView);
    m_pToolbarSemiMeasure->attach(ui->menuAutoMeasure);
    addToolBar(Qt::TopToolBarArea, m_pToolbarSemiMeasure);

    m_pSemiAutoDialog = new Qly::DialogSemiAutoMeasure(&m_pMeasureView->dataSet(), this);
    connect(m_pToolbarSemiMeasure, &Qly::ToolBarSemiAutoMeasure::showSetupDialog, m_pSemiAutoDialog, &Qly::DialogSemiAutoMeasure::show);
    connect(m_pToolbarSemiMeasure, &Qly::ToolBarSemiAutoMeasure::checked, m_pToolbarMeasure, &Qly::ToolBarMeasure::uncheckAll);
    connect(m_pToolbarMeasure, &Qly::ToolBarMeasure::checked, m_pToolbarSemiMeasure, &Qly::ToolBarSemiAutoMeasure::uncheckAll);

    m_pSemiAutoMeasure = new Qly::SemiAutoMeasure(&m_pMeasureView->dataSet());

    connect(&m_pMeasureView->dataSet(), &Qly::MeasureDataSet::elementAdded, this, &MainWindow::onElementAdded);

}

void MainWindow::setupLensManager(QSettings &settings)
{
    m_pLensManager = new Qly::LensManager; // LensManager 是信息集中地，物镜的转换信息全都发送到这里
    m_pLensManager->loadSettings(settings);

    //    qDebug() << "m_pLensManager->loadSettings(settings);";
    //   qDebug() << m_pLensManager->currentLensIndex();
    m_toolbarNosepiece = new Qly::ToolBarNosepiece(this);
    m_toolbarNosepiece->attach(m_pLensManager);
    addToolBar(m_toolbarNosepiece);

    connect(m_pLensManager, &Qly::LensManager::lensChanged, this, &MainWindow::onLensChanged);

    m_lensDialog = new Qly::LensManageDialog(m_pLensManager, this);

    connect(ui->actionCalib, &QAction::triggered, this, &MainWindow::showCalibDialog);
    connect(ui->actionLensManage, &QAction::triggered, this , &MainWindow::showLensManageDialog);

    if(m_pLensManager->currentLensIndex() == -1) return;
    double pixelSize_um = m_pLensManager->currentLens().pixelSize_um;
    m_pMeasureView->setPixelSize(pixelSize_um, 0);
    double rulerLength_um = m_pLensManager->currentLens().rulerLength_um;
    QString rulerText = m_pLensManager->currentLens().rulerText;
    QPoint rulerPos = m_pLensManager->rulerPosition();
    int lineWidth = m_pLensManager->rulerLineWidth();
    Qt::GlobalColor color = m_pLensManager->rulerColor();
    int fontSize = m_pLensManager->rulerFontSize();
    m_pMeasureView->ruler().setFontSize(fontSize);
    m_pMeasureView->setPixelSize(pixelSize_um, 1);
    m_pMeasureView->ruler().setEnable(true);
    m_pMeasureView->ruler().setColor(color);
    m_pMeasureView->ruler().setPosition(rulerPos);
    m_pMeasureView->ruler().setLineWidth(lineWidth);
    m_pMeasureView->ruler().setRuler(rulerLength_um, rulerText);
    m_pMeasureView->update();
}

void MainWindow::setupCamera(QSettings &settings)
{
    m_toolbarCamera = new Qly::ToolBarCamera("ToolBarCamera", this);
    m_toolbarCamera->attach(m_cameraImage, true);
    m_toolbarCamera->hideFlipSettings(false);
    m_toolbarCamera->hideBayerSettings(false);
    addToolBar(Qt::LeftToolBarArea, m_toolbarCamera);
    m_toolbarCamera->loadSettings(settings);

    ui->menuCamera->addAction(m_toolbarCamera->actionDefaultCamera);
    ui->menuCamera->addAction(m_toolbarCamera->actionStartLive);
    ui->menuCamera->addAction(m_toolbarCamera->actionSetupCamera);
    ui->menuCamera->addAction(m_toolbarCamera->actionImageHFlip);
    ui->menuCamera->addAction(m_toolbarCamera->actionImageVFlip);
    ui->menuCamera->addAction(m_toolbarCamera->actionGrayMode);
    //m_pCamera = new Qly::CameraHikVision(this);

    QString path = qApp->applicationDirPath() + "/Camera/";
    m_cameraFind = new Qly::CameraFinder(path, this);

    //m_pCamera = new Qly::PCCamera(this);
    //m_pCamera = new Qly::ScreenCamera(this);
    connect(m_toolbarCamera, &Qly::ToolBarCamera::defaultCamera, this, &MainWindow::openDefaultCamera);
    connect(m_toolbarCamera, &Qly::ToolBarCamera::closeCamera, this, &MainWindow::closeCamera);

    //connect(m_pMeasureView, &Qly::MeasureView::mouseRightClick, this, &MainWindow::toggleCameraState);
}

void MainWindow::setupStatusBar()
{
    m_labelMousePosition = new QLabel("(0, 0)", this);
    m_labelCameraName = new QLabel("Camera: ", this);
    m_labelCameraPixelFormat = new QLabel("PixelFormat: ", this);
    m_labelCameraResolution = new QLabel("Resolution: ", this);
    m_labelCameraFrameCount = new QLabel("FrameCount: ", this);
    m_labelCameraFrameRate = new QLabel("FrameRate: ", this);

    m_labelFocusMeasure = new QLabel("FocusMeasure", this);

    m_labelCameraName->setMargin(1);
    statusBar()->addWidget(m_labelMousePosition);
    statusBar()->addWidget(m_labelCameraName);
    statusBar()->addWidget(m_labelCameraPixelFormat);
    statusBar()->addWidget(m_labelCameraResolution);
    statusBar()->addWidget(m_labelCameraFrameCount);
    statusBar()->addWidget(m_labelCameraFrameRate);

    statusBar()->addWidget(m_labelFocusMeasure);

    QFontMetrics fm(m_labelMousePosition->font());
    qDebug() <<"xxx = " <<  fm.size(Qt::TextSingleLine, "Resolution: (640, 480)").width();
    m_labelMousePosition->setMinimumWidth(fm.size(Qt::TextSingleLine, "(1920.000, 1080.000)").width() + 10);
    m_labelCameraName->setMinimumWidth(fm.size(Qt::TextSingleLine, "Camera: Unknow Camera").width() + 10);
    m_labelCameraPixelFormat->setMinimumWidth(fm.size(Qt::TextSingleLine, "PixelFormat: RGB32").width() + 10);
    m_labelCameraResolution->setMinimumWidth(fm.size(Qt::TextSingleLine, "Resolution: (640, 480)").width() + 10);
    m_labelCameraFrameCount->setMinimumWidth(fm.size(Qt::TextSingleLine, "FrameCount: 99999").width() + 10);
    m_labelCameraFrameRate->setMinimumWidth(fm.size(Qt::TextSingleLine, "FrameRate: 99999").width() + 10);
    m_labelFocusMeasure->setMinimumWidth(fm.size(Qt::TextSingleLine, "Focus: 9999999").width() + 10);

    m_timerStatusBar = new QTimer(this);
    m_timerStatusBar->setInterval(1000);
    connect(m_timerStatusBar, &QTimer::timeout, this, &MainWindow::onTimeoutFrameRateCounter);
    m_timerStatusBar->start();

    connect(m_pMeasureView, &Qly::ImageView::mouseMoved, this, &MainWindow::updateMousePos);
}

void MainWindow::setupNosepiece(QSettings &settings)
{

    QString path = qApp->applicationDirPath() + "/Nosepiece/";
    QDir dir(path);
    QStringList filters;
    filters << "NosepieceOUMIT*.dll";
    QStringList dllNames = dir.entryList(filters, QDir::Files, QDir::NoSort);
    if(dllNames.isEmpty()) return;
    qDebug() << "setupNosepiece: DLL NAME = " << dllNames[0];
    pNosepieceLib = new Qly::NosepieceLibLoader(path + dllNames[0], this);

    m_pNosepiece = pNosepieceLib->createInstance(this);
    if(m_pNosepiece)
    {
        connect(m_pNosepiece, &Qly::NosepieceInterface::lensChanged, m_pLensManager, &Qly::LensManager::setLens); //所有的信号都给到LensManager，然后由 LensManager 分发
        connect(m_pLensManager, &Qly::LensManager::lensChanged, m_pNosepiece, qOverload<int, int>(&Qly::NosepieceInterface::setLens));

        m_pNosepiece->loadSettings(settings);
    }
}

void MainWindow::savePassword(QSettings &settings)
{
    QString pwd = settings.value("Global/Password", "").toString();
    if(pwd != m_password)
    {
        settings.setValue("Global/Password", m_password);
    }
}

void MainWindow::onElementAdded(Qly::MeasureElement *p)
{
    QImage &image = m_cameraImage->imageRef();
    cv::Mat mat = QImage2cvMat(image);
    cv::Mat gray = color2gray(mat);

    m_pSemiAutoMeasure->semiAutoMeasure(p, gray);
}

void MainWindow::updateCameraFrame(Qly::VideoFrame frame)
{
    m_cameraImage->setVideoFrame(frame);
    m_labelCameraPixelFormat->setText(tr("PixelFormat: %1").arg(Qly::PixelFormat2QString(frame.format)));
    m_labelCameraResolution->setText(tr("Resolution: (%1, %2)").arg(frame.width).arg(frame.height));
    m_labelCameraFrameCount->setText(tr("FrameCount: %1").arg(m_cameraImage->imageCount()));
}

void MainWindow::updateCameraImage(const uint8_t *imgBuf, int stride, QSize size, AVPixelFormat format)
{
    m_cameraImage->setImageData(imgBuf, stride, size, format);
    m_labelCameraPixelFormat->setText(tr("PixelFormat: %1").arg(Qly::PixelFormat2QString(format)));
    m_labelCameraResolution->setText(tr("Resolution: (%1, %2)").arg(size.width()).arg(size.height()));
    m_labelCameraFrameCount->setText(tr("FrameCount: %1").arg(m_cameraImage->imageCount()));
}

void MainWindow::onTimeoutFrameRateCounter()
{
    static int oldImageCount = 0;
    int currentImageCount = m_cameraImage->imageCount();
    int frameRate = currentImageCount - oldImageCount;
    oldImageCount = currentImageCount;
    m_labelCameraFrameRate->setText(tr("FrameRate: %1 fps   ").arg(frameRate));
}

void MainWindow::onLensChanged(int oldLens, int newLens)
{
    Q_UNUSED(oldLens);
    Q_UNUSED(newLens);
    if(m_pLensManager->currentLensIndex() == -1) return;
    double pixelSize_um = m_pLensManager->currentLens().pixelSize_um;
    double rulerLength_um = m_pLensManager->currentLens().rulerLength_um;
    QString rulerText = m_pLensManager->currentLens().rulerText;
    QPoint rulerPos = m_pLensManager->rulerPosition();
    int lineWidth = m_pLensManager->rulerLineWidth();
    Qt::GlobalColor color = m_pLensManager->rulerColor();
    int fontSize = m_pLensManager->rulerFontSize();
    m_pMeasureView->setPixelSize(pixelSize_um, 1);
    m_pMeasureView->ruler().setEnable(true);
    m_pMeasureView->ruler().setColor(color);
    m_pMeasureView->ruler().setPosition(rulerPos);
    m_pMeasureView->ruler().setFontSize(fontSize);
    m_pMeasureView->ruler().setLineWidth(lineWidth);
    m_pMeasureView->ruler().setRuler(rulerLength_um, rulerText);
    m_pMeasureView->update();
}

void MainWindow::updateLensInfo()
{
    double pixelSize_um = m_pLensManager->currentLens().pixelSize_um;
    m_pMeasureView->setPixelSize(pixelSize_um, 1);

    double rulerLength_um = m_pLensManager->currentLens().rulerLength_um;
    QString rulerText = m_pLensManager->currentLens().rulerText;
    QPoint rulerPos = m_pLensManager->rulerPosition();
    int lineWidth = m_pLensManager->rulerLineWidth();
    int fontSize = m_pLensManager->rulerFontSize();
    Qt::GlobalColor color = m_pLensManager->rulerColor();
    //    qDebug() << "color = " << color;
    m_pMeasureView->setPixelSize(pixelSize_um, 1);
    m_pMeasureView->ruler().setEnable(true);
    m_pMeasureView->ruler().setColor(QColor(color));
    m_pMeasureView->ruler().setPosition(rulerPos);
    m_pMeasureView->ruler().setLineWidth(lineWidth);
    m_pMeasureView->ruler().setFontSize(fontSize);
    m_pMeasureView->ruler().setRuler(rulerLength_um, rulerText);
    m_pMeasureView->update();
}

void MainWindow::updateFocusMeasure(QImage &image, double score)
{
    Q_UNUSED(image);
    m_labelFocusMeasure->setText(tr("Focus: %1").arg(score));
}

void MainWindow::toggleCameraState()
{
    if(m_pCamera->isLive())
    {
        m_saveImage = true;
    }
    m_toolbarCamera->toggleStartStopCamera();
}

QString md5(QString str)
{
    QByteArray bytePwd = str.toUtf8();
    QByteArray bytePwdMd5 = QCryptographicHash::hash(bytePwd, QCryptographicHash::Md5);
    QString strPwdMd5 = bytePwdMd5.toHex();
    return strPwdMd5;
}

void MainWindow::changePassword()
{
    bool ok = false;
    QString pw = QInputDialog::getText(this, u8"管理员权限验证", u8"请输入当前的管理员密码:", QLineEdit::Password, "", &ok );
    if(!ok)
    {
        //        QMessageBox::information(this, QStringLiteral("Error"), u8"密码输入错误，无权访问此功能!" );
        return ;
    }
    QString strPwdMd5 = md5(pw);

    if( m_password != strPwdMd5)
    {
        QMessageBox::information(this, QStringLiteral("Error"), u8"密码输入错误，退出!" );
        return ;
    }
    QString pw1 = QInputDialog::getText(this, u8"更新管理员密码", u8"请输入新的管理员密码:", QLineEdit::Password, "", &ok );
    if(!ok || pw1.isEmpty())
    {
        QMessageBox::information(this, QStringLiteral("Error"), u8"密码输入错误，错误!" );
        return ;
    }

    QString pw2 = QInputDialog::getText(this, u8"更新管理员密码", u8"请再次输入新的管理员密码:", QLineEdit::Password, "", &ok );
    if(!ok || pw2.isEmpty())
    {
        QMessageBox::information(this, QStringLiteral("Error"), u8"密码输入错误，错误!" );
        return ;
    }

    if(pw1 != pw2)
    {
        QMessageBox::information(this, QStringLiteral("Error"), u8"两次密码不同，请重新设置密码!" );
        return ;
    }
    m_password = md5(pw1);
    QSettings settings("JingHai Technology", "JHPhotoV2", this );
    savePassword(settings);

}

void MainWindow::setClibMode(bool on)
{
    if(on)
    {
        m_pToolbarMeasure->uncheckAll();
    }
}

void MainWindow::showCalibDialog()
{
    bool ok;
    Qly::MeasureDataSet & data = m_pMeasureView->dataSet();
    if(data.elementList().size() == 0 || data.elementList().last()->type() != Qly::MeasureElement::Line) //改成 Qly::MeasureElement::ParallelLine
    {
        QMessageBox::information(this, QStringLiteral("Error"), u8"请先拉一个标尺!" );
        return ;
    }
    const QVector<double> &res = data.elementList().last()->results_pix();
    CalibDialog dia(this);
    dia.setWindowFlag(Qt::WindowContextHelpButtonHint, false);
    QString name = m_pLensManager->currentLens().displayName;
    dia.setNameLength(name, res[0]);
    if(dia.exec())
    {
        double um_per_pixel = dia.umPerPixel();
        m_pLensManager->currentLens().pixelSize_um = um_per_pixel;
        m_pMeasureView->setPixelSize(um_per_pixel,  0);
    }
}


void MainWindow::showLensManageDialog()
{
    bool ok = false;
    QString pw = QInputDialog::getText(this, u8"管理员权限验证", u8"此功能只对管理员开放，请输入管理员密码:", QLineEdit::Password, "", &ok );
    if(!ok)
    {
        //        QMessageBox::information(this, QStringLiteral("Error"), u8"密码输入错误，无权访问此功能!" );
        return ;
    }

    QByteArray bytePwd = pw.toUtf8();
    QByteArray bytePwdMd5 = QCryptographicHash::hash(bytePwd, QCryptographicHash::Md5);
    QString strPwdMd5 = bytePwdMd5.toHex();
    //    qDebug() << strPwdMd5;
    if( m_password != strPwdMd5)
    {
        QMessageBox::information(this, QStringLiteral("Error"), u8"密码输入错误，无权访问此功能!" );
        return ;
    }

    Qly::LensManageDialog lensDialog(m_pLensManager, this);
    lensDialog.setWindowFlag(Qt::WindowContextHelpButtonHint, false);
    connect(&lensDialog, &Qly::LensManageDialog::lensDataChanged, this, &MainWindow::updateLensInfo);
    int ret = lensDialog.exec();
    if(ret == QDialog::Accepted)
    {
        lensDialog.dumpLensData(m_pLensManager);
        updateLensInfo();
    }

    disconnect(&lensDialog, &Qly::LensManageDialog::lensDataChanged, this, &MainWindow::updateLensInfo);
}


void MainWindow::redChannel()
{
    m_cameraImage->push();
    ImageToGray g;
    g.redChannel(m_cameraImage->imageRef());
    m_pMeasureView->update();
}
void MainWindow::blueChannel()
{
    m_cameraImage->push();
    ImageToGray g;
    g.blueChannel(m_cameraImage->imageRef());
    m_pMeasureView->update();
}
void MainWindow::greenChannel()
{
    m_cameraImage->push();
    ImageToGray g;
    g.greenChannel(m_cameraImage->imageRef());
    m_pMeasureView->update();
}

void MainWindow::rotateOrFlip()
{
    m_cameraImage->push();
    ImageFlip flip(1);
    if(sender() == ui->actionFlipVertical)
    {

    }
    else
    {

    }
    flip.apply(m_cameraImage->imageRef());
    m_pMeasureView->update();
}
void MainWindow::setupImageProcessing()
{
    ui->actionUndo->setEnabled(m_cameraImage->undoStatus());
    connect(m_cameraImage, &Qly::CameraImage::undoStatusChanged, ui->actionUndo, &QAction::setEnabled);
    connect(ui->actionUndo, &QAction::triggered, m_cameraImage, &Qly::CameraImage::undo);
    connect(ui->actionToGray, &QAction::triggered, this, &MainWindow::colorImageToGray);
    connect(ui->actionFetchRed, &QAction::triggered, this, &MainWindow::redChannel);
    connect(ui->actionFetchBlue, &QAction::triggered, this, &MainWindow::blueChannel);
    connect(ui->actionFetchGreen, &QAction::triggered, this, &MainWindow::greenChannel);
    connect(ui->actionFlipVertical, &QAction::triggered, this, &MainWindow::rotateOrFlip);

}

void MainWindow::colorImageToGray()
{
    qDebug() <<"colorImageToGray";
    m_cameraImage->push();
    ImageToGray g;
    g.apply(m_cameraImage->imageRef());
    m_pMeasureView->update();
}

void MainWindow::clearAllMark()
{
    Qly::MeasureDataSet & data = m_pMeasureView->dataSet();
    data.clearAll();
    m_pMeasureView->update();
}

void MainWindow::updateMousePos(const QPointF &p)
{
    //  double scale = m_pLensManager->currentLens().pixelSize_um;

    double pixelSize_um = 1.0;
    if(m_pLensManager)
    {
        pixelSize_um = m_pLensManager->currentLens().pixelSize_um;
    }
    //m_labelMousePosition->setText(QString("(%1, %2)").arg(p.x()).arg(p.y()));
    m_labelMousePosition->setText(QString("(%1, %2)").arg(p.x() * pixelSize_um).arg(p.y() * pixelSize_um));
}


void MainWindow::setDefaultAppInfo()
{
    m_appName = u8"JHPhoto 显微图像处理软件 v2.0";
    m_companyName = u8"北京经海科技有限公司";
    m_author = u8"李渊";
    m_website = u8"jinghai_tech@163.com";
    m_phoneNumber = u8"15011086631";
    m_appIcon = QIcon(u8":/jh-logo.png");

    connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::showAbout);
}

void MainWindow::showAbout()
{
    m_aboutDialog = new AboutDialog(this);
    m_aboutDialog->setAppName(m_appName);
    m_aboutDialog->setCompanyName(m_companyName);
    m_aboutDialog->setWebSite(m_website);
    m_aboutDialog->setPhoneNumber(m_phoneNumber);
    m_aboutDialog->setIcon(m_appIcon);
    m_aboutDialog->exec();

    delete m_aboutDialog;
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_Space:
        m_toolbarCamera->toggleStartStopCamera();
        break;
    }
    QMainWindow::keyPressEvent(event);
}

bool MainWindow::isSafeToClose()
{
    if(m_cameraImage->isModified())
    {
        int ret = QMessageBox::warning(this,
                                       tr("JHPhoto"),
                                       tr("The image has unsaved changes.\n Do you want to save it before it is closed?"),
                                       QMessageBox::Discard| QMessageBox::Cancel);
        switch (ret)
        {
        case QMessageBox::Cancel:
            return false;
        default:
            return true;
        }
    }
    return true;
}


void MainWindow::closeEvent(QCloseEvent *event)
{
    if(isSafeToClose())
    {
        QString path = configFilePath();
        QSettings settings("JingHai Technology", "JHPhotoV2", this );
        if(m_pLensManager) m_pLensManager->writeSettings(settings);
        if(m_pToolbarZoom) m_pToolbarZoom->writeSettings(settings);
        if(m_pToolbarProperty) m_pToolbarProperty->writeSettings(settings);

        settings.setValue("Global/LoadImagePath", m_loadImagePath);
        settings.setValue("Global/SaveImagePath", m_saveImagePath);
        settings.setValue("Geometry/MainWindow", saveGeometry());
        settings.setValue("Geometry/windowState", saveState());
        if(m_pCamera && m_pCamera->isLive())
        {
            m_pCamera->stopGrabbing();
            m_pCamera->saveSettingsToFile(path + "/Camera.ini");
            m_pCamera->close();
            // delete m_pCamera;
            // m_pCamera = nullptr;
        }

        event->accept();
    }
    else
    {
        event->ignore();
    }
    QMainWindow::closeEvent(event);
}

